package forums.dao;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.springframework.util.Assert;

import forums.model.Forum;
import forums.model.Message;

/*
 * Author       :       Willie Wheeler and John Wheeler
 * Book         :       'Spring In Practice' [Book written by Willie Wheeler and John Wheeler]
 */
class ObjectFactory {
	private static final ObjectFactory INSTANCE = new ObjectFactory();
	
	private final SortedMap<Long, Forum> forums = new TreeMap<Long, Forum>();
	private final Map<Long, Message> messages = new HashMap<Long, Message>();
	private final DateFormat format = new SimpleDateFormat("MM/dd/yy");
	
	public static ObjectFactory instance() {
		return INSTANCE;
	}
	
	private ObjectFactory() {
		buildForum(100L, "Announcements");
		buildForum(101L, "Core Container");
		buildForum(102L, "Data Access");
		buildForum(103L, "Web");
		buildForum(104L, "Spring Web Flow");
		buildForum(105L, "Spring Security");
		
		buildMsg(100L, 100L, "Maintenance policy updated", "julia", "09/28/08");
		buildMsg(101L, 100L, "Spring Security news", "juan", "09/30/08");
		buildMsg(102L, 100L, "Spring 3 released", "julia", "10/01/08");
		
		buildMsg(103L, 101L, "p namespace", "elvira", "09/29/08");
		buildMsg(104L, 101L, "difference between IOC and DI??", "paula", "09/30/08");
		buildMsg(105L, 101L, "buy v1@gRA online!", "elvira", "09/30/08");	// spam
		buildMsg(106L, 101L, "Wherefore Spring?", "daniel", "10/01/08");
		buildMsg(107L, 101L, "What is Spring?", "daniel", "10/01/08");
		
		buildMsg(108L, 102L, "to ORM or not to ORM", "julia", "09/27/08");
		buildMsg(109L, 102L, "jdbc template acting funny??", "juan", "10/01/08");
		buildMsg(110L, 102L, "Hibernate woes", "julia", "10/01/08");
		
		buildMsg(111L, 104L, "FINALLY GOT IT WORKING", "elvira", "09/29/08");
		buildMsg(112L, 104L, "Where do i put the flow config file", "daniel", "09/30/08");
		buildMsg(113L, 104L, "OGNL vs unified EL", "paula", "10/01/08");
		buildMsg(114L, 104L, "Can you help debug my checkout process", "julia", "10/01/08");
		buildMsg(115L, 104L, "Subflow trouble", "julia", "10/01/08");
		
		buildMsg(116L, 105L, "Should I use basic login or form-based login? HELP", "elvira", "09/23/08");
		buildMsg(117L, 105L, "Different kinds of secure object", "daniel", "09/28/08");
		buildMsg(118L, 105L, "Trying to understand voters...", "julia", "09/30/08");
		buildMsg(119L, 105L, "GrantedAuthority = role?", "paula", "09/30/08");
		
		// Suppress a message
		createMessage(105L).setVisible(false);
	}
	
	private void buildForum(Long id, String name) {
		forums.put(id, new Forum(id, name));
	}
	
	private void buildMsg(Long id, Long forumId, String subject, String author, String dateStr) {
		Date date = null;
		try {
			date = format.parse(dateStr);
		} catch (ParseException e) {
			// this shouldn't happen
		}
		
		Forum forum = createForum(forumId);
		Message msg = new Message(id, forum, subject, author, date);
		messages.put(id, msg);
		forum.getMessages().add(msg);
	}
	
	public List<Forum> createForums() {
		return new ArrayList<Forum>(forums.values());
	}
	
	public Forum createForum(Long id) {
		Assert.notNull(id, "id required");
		return forums.get(id);
	}
	
	public Message createMessage(Long id) {
		Assert.notNull(id, "id required");
		return messages.get(id);
	}
}
